home *** CD-ROM | disk | FTP | other *** search
-
- ASSEMBLERKURS - LEKTION 3
-
- Nun fahren wir mit der Praxis fort, ich rate euch vorher aber, 68000.TXT
- in einen Textbuffer zu laden, es ist eine Art Zusammenfassung von
- Lektion2. Diese wird euch nützlich sein, wenn ihr eine Adressierungsart
- vergessen habt oder mit einem Befehl nichts mehr anzufangen wißt, da diese
- Lektion eine gewisse Vertrautheit mit ihnen voraussetzt. In diesem Text
- sind alle Adressierungen erklärt, auch jene, die nur sehr selten verwendet
- werden, deswegen lest ihn aber sorgt euch nicht, wenn ihr einige Dinge
- nicht versteht, wie z.B. die Adressierung mit INDEX, denn in Lektion3 wird
- sie noch nicht verwendet!
-
- In diesem Kapitel beginnen wir damit, etwas auf dem Bildschirm
- darzustellen: um das zu erreichen, müssen wir eine COPPERLIST schreiben,
- das ist ein Programm für den COPPER-Chip, dem Typen, der dir Grafik
- steuert, wir haben ihn bereits verwendet, um die Bildschirmfarbe zu ändern
- ($dff180 ist ein Register des Copper, das COLOR0 heißt). Bis jetzt aber
- haben wir die Register nur direkt mittels Prozessor angesprochen, und wie
- ihr beim Debuggen der Listings bemerkt haben werdet, sind nur kurze
- "Lichtblitze" in der Farbe aufgetreten, die wir hineinschrieben, sofort
- aber ersetzte die Farbe des Betriebssystemes, oder des ASMONE, unsere
- eigene. Nur in einer Schleife, bei der dauernd eine Zahl in das Register
- geschieben wurde, schafften wir es, den ganzen Bildschirm zu färben, aber,
- kaum aus dem Programm ausgestieben, kehrt erbarmungslos der alte Zustand
- zurück. Das ist darauf zurückzuführen, daß alles, was wir auf dem
- Bildschirm sehen - Fenster, Schriften und der Rest - ist das Ergebnis
- einer COPPERLIST, genauer einer SYSTEM-COPPERLIST. Diese ist nichts
- anderes als eine Art:
-
- MOVE.W #$123,dff180 ; COLOR0 - Beschreibe Farbe 0
- MOVE.W #$456,dff182 ; COLOR1 - Beschreibe Farbe 1
- etc....
-
- Diese wird dauernd ausgeführt, und hier liegt auch die Erklärung, warum
- die System-Farbe sofort zurückkehrt, wenn nur mit dem Prozessor in die
- Register schreiben: weil die Copperlist jede 1/50 Sekunde alle Farben neu
- definiert!!! Nun werdet ihr ahnen, daß es schier unmöglich sein wird, eine
- Figur in Ruhe und Frieden auf den Bildschirm zu bringen, wenn man dauernd
- mit der Copperlist des Betriebssystemes zu kämpfen hat, die dauernd alles
- umdefiniert. Wir müßten unsere eigene Copperlist erstellen und sie mit der
- des Systemes ersetzen... NICHTS LEICHTER ALS DAS! Wie ich schon
- prophezeiht habe, ist die Copperlist nichts anderes als eine Schlange von
- MOVE, die Werte in die Register des Copper geben, also den
- $dffxxx-Registern. Diese Move aber werden nicht vom Prozessor, sondern vom
- Copper selbst gemacht, der unabhängig vom Prozessor läuft und den für
- andere Sachen freihält... das ist einer der Gründe, wieso sie auf PC nicht
- LIONHEART oder PROJECT X des Amiga haben. Wir müssen ihm also wirklich ein
- Listing schreiben, wie wir es vom 68000er her kennen, und danach den
- Copper darüber informieren, wo es sich befindet und es ihn an Stelle der
- Workbench-Copperlist ausführen lassen. Der Copper besitzt nur 3 Befehle,
- wovon in der Praxis nur zwei verwendet werden: diese sind ein MOVE und ein
- WAIT; derjenige, den niemand verwendet, ist das SKIP, deswegen behandeln
- wir es nur, wenn wir ein Listing damit finden.
-
- Das MOVE ist kinderleicht: könnt ihr euch an das erinnern ? :
-
- MOVE.W #$123,dff180 ; Gib die Farbe RGB in COLOR0
-
- Gut, in Copperlist schaut das so aus:
-
- dc.w $180,$123 ; die Zahlen werden direkt mit dc.w
- ; in den Speicher gegeben, aber wir
- ; müssen ja nur zwei Befehle lernen!!
-
- Das heißt, man muß zuerst die Adresse angeben, in die der Wert kommt (ohne
- dem $dff, so wie wir es schon gesehen haben wenn wir in a0 $dff180 gegeben
- haben: $180(a0). Genauso haben die Entwickler daran gedacht, uns das
- dauernde $dff zu ersparen, und so reicht es, wenn wir $180 oder $182 oder
- was auch immer, schreiben. Hauptsache, wir beschreiben nur Copperregister,
- denn nur Register des COPPER können mit der COPPERLIST angesteuert
- werden!! Weiters darf nur auf GERADE Adressen zugegriffen werden, wie
- $180, $182 ..., NIE $181, $179 etc, weiters können nur WORD verwendet
- werden. Wie ihr seht, wird die COPPERLIST nicht auf die gleiche Art
- assembliert wie die Instruktionen des 68000, bei denen aus Befehlen wie
- RTS, MOVE... $4e75 usw. wird, sondern es müssen die BYTES so in den
- Speicher gelegt werden, wie sie der Coprozessor Copper lesen kann. Deshalb
- verwenden wir das DC, um Byte für Byte die Befehle hineinzuschreiben, aber
- es ist sehr einfach! Z.B. um die ersten vier Farben zu definieren:
-
- COPPERLIST:
- dc.w $180,$000 ; COLOR0 = SCHWARZ
- dc.w $182,$f00 ; COLOR1 = ROT
- dc.w $184,$0f0 ; COLOR2 = GRÜN
- dc.w $186,$00f ; COLOR3 = BLAU
-
- Erinnert ihr euchm wie das Farbformat aussieht? RGB = RED , GREEN, BLUE.
- Um einen Kommentar über die $dffxxx - Register zu erhalten, könnt ihr
- jederzeit "=C" schreiben, oder, speziell Z.B. für $dff180 "=C 180", und
- ihr werdet eine Zusammenfassung in englisch bekommen. Probiert z.B. "=C
- 006" und ihr werdet Namen und Erklärung über dieses Register bekommen, das
- ihr verwendet habt, um den Bildschirm zum Blinken zu bringen. Um alle
- Register zu sehen, "=C".
-
- Das WAIT hingegen dient dazu, eine bestimmte Zeile abzuwarten, wenn man
- z.B. die Hintergrundfarbe (COLOR0) bis zur Hälfte des Bildschirmes
- schwarz, und von da ab blau machen möchte, dann sieht das so aus:
-
- dc.w $180,0 ; COLOR0 Schwarz
-
- gefolgt von einem WAIT, das die Mitte des Bildschirmes abwartet, und dann
-
- dc.w $180,$00F ; COLOR0 Blau
-
- Mit dieser Strategie kann man die ganze Palette (die Farbliste) in jeder
- Bildschrirmzeile verändern, von so was können die PC mit VGA nur träumen,
- denn in der Tat haben die meisten Amiga-Spiele nur Screens mit 32 Farben,
- aber durch ändern der Farbpalette hie und da, z.B. wenn das Spielfeld nach
- unten scrollt, kann man mehr Farben erzeugen als eine VGA mit 256 Farben.
- Vor allem wenn man in Betrachtung zieht, daß man einen Farbverlauf im
- Hintergrund erzeugen kann, indem man bei jeder Bildschirmzeile Farbe
- wechselt, und das wird unser erstes Programm in dieser Lektion sein. Der
- WAIT-Befehl präsentiert sich so:
-
- dc.w $1007,$FFFE ; WAIT Koordinate X = $10, Y = $07
-
- Dieser Befehl bedeutet: WARTE DIE HORIZONTALE LINIE $10 AB, SPALTE 7 (also
- der siebte Punkt von links, diese "Punkte" werden Pixel genannt). Das
- $FFFE steht für WAIT, es muß immer gesetzt werden, während das erste Byte
- die horizontale Linie (x) ist, die es abzuwarten gilt, und das zweite Byte
- die Vertikale (y). Der Bildschirm besteht aus vielen kleinen Punkten, die
- alle aneinander gereiht sind, wie ein Blatt Papier mit kleinen Kästchen,
- Millimeterpapier in etwa. Um den Punkt (Pixel) an Position 16,7
- anzupeilen, also der 16. Punkt vom oberen Rand und der 7. vom linken Rand
- nach rechts, werden wir $1007 ($10 = 16!) schreiben. Wie bei Schiffe
- versenken! Normalerweise gibt man nur die horizontale Linie an ihrem
- Anfang an, der ist $07 statt $01, weil der Rest über dem linken Rand des
- Monitors liegt. Der WAIT-Befehl wird auch dazu verwendet, das Ende der
- Copperlist zu kennzeichnen. Am Ende der COP setzt man ein
-
- dc.w $FFFF,$FFFE ; Ende Copperlist
-
- Dies interpretiert der Copper per Definition als Ende, auch weil es
- bedeuten würde, eine Linie abzuwarten, die es nicht gibt! Die Copperlist
- startet dann von vorne. Es hat sich auch rumgesprochen, daß bei einigen
- älteren Amigamodellen zwei abschließende Instruktionen nötig seien, aber
- es scheint eine Art von Massenpsychose zu sein, da niemand jemals zwei
- verwendet hat und alles immer funktionierte.
-
- Um unsere Copperlist zu schreiben, die am Anfang noch ohne Bilder sein
- wird, lediglich mit einigen Farbverläufen, müssen wir die BITPLANE
- abschalten, also die aus Bits bestehenden "Ebenen", die übereinander
- gelegt die Bilder erzeugen. Um da zu erreichen, setzen wir am Anfang ein
- DC.W $100,$200 ein, wir geben also den Wert $200 ins Register $dff200, das
- das Kontrollregister der Bitplane ist.
-
- NUN SIND WIR IMSTANDE, EINE VOLLSTÄNDIGE COPPERLIST ZU SCHREIBEN, DIE BIS
- MITTE BILDSCHIRM GEHT UND DANN FARBE WECHSELT!
-
- Copperlist:
- dc.w $100,$200 ; BPLCON0 Keine Bilder, nur Hintergrund
- dc.w $180,0 ; COLOR0 Schwarz (Hintergrund)
- dc.w $7f07,$FFFE ; WAIT - warte Linie $7f ab (127)
- dc.w $180,$00f ; COLOR0 Blau
- dc.w $FFFF,$FFFE ; ENDE DER COPPERLIST
-
- Wenn man bedenkt, daß ihr die Funktionstüchtigkeit eurer Copperlisten
- überprüfen wollen werdet, hier eine TABELLE ZUM NACHSCHLAGEN DER FARBEN
- DES COPPER:
-
- Der Amiga besitzt 32 Register für dementsprechend vielen verschiedenen
- Farben:
-
- $dff180 ; COLOR0 (Hintergrund)
- $dff182 ; COLOR1
- $dff184 ; COLOR2
- $dff186 ; COLOR3
- ...
- $dff1be ; COLOR31
-
- In jedes dieser Register kann eine der 4096 möglichen Farben kommen, die
- durch Mischen der drei Grundfarben Rot, Grün und Blau zustande kommen
- können. Jede dieser Farben kann eine Intensität von 0 bis 15 haben, also
- 16 "Helligkeitsstufen". Nachgerechnet ergibt sich aus allen möglichen
- Kombinationen, 16*16*16=4096, eben die Anzahl der darstellbaren Farben (16
- Farbtöne Rot, 16 von Grün und 16 von Blau). Den Wert der Farbe kann man
- entweder mit dem Prozessor oder mit dem Copper eingeben:
-
- move.w #$000,$dff180 ; Farbe SCHWARZ in COLOR0
-
- dc.w $180,$FFF ; Farbe WEIß in COLOR0
-
- In diesem Beispiel haben wir die zwei Extremwerte gesehen: $FFF, gleich
- Weiß, und $000, Schwarz. Um die Farbe zu wählen muß man bedenken, daß das
- WORD der Farbe so aufgebaut ist:
-
- dc.w $0RGB
-
- wobei die vierte 0 (ganz links) nicht verwendet wird, und gilt:
-
- R = ROT -Komponente der Farbe (RED)
- G = GRÜN-Komponente der Farbe (GREEN)
- B = BLAU-Komponente der Farbe (BLUE)
-
- Die Bit vom 15 bis zum 12 sind nicht verwendet, die Bit von 11 bis 8
- stellen den Rotanteil dar, Bit 7 bis Bit 4 den Grünanteil und Bit 4 bis
- Bit 0 den Blauanteil.
-
- Jede RGB-Farbe kann einen Wert von 0 bis 15 haben, also von $0 bis $15 in
- Hexadezimal, es ist also leicht eine Farbe auszuwählen:
-
- $FFF = Weiß
- $D00 = Ziegelrot
- $F00 = Rot
- $F80 = Rot-Orange
- $F90 = Orange
- $fb0 = Goldgelb
- $fd0 = Cadmiumgelb
- $FF0 = Zitrone
- $8e0 = Hellgrün
- $0f0 = Grün
- $2c0 = Dunkelgrün
- $0b1 = Baumgrün
- $0db = Wasser
- $1fb = Wasser Hell
- $6fe = Himmelblau
- $6ce = Helles Blau
- $00f = Blau
- $61f = Brillantes Blau
- $06d = Dunkelblau
- $c1f = Violett
- $fac = Rosa
- $db9 = Beige
- $c80 = Braun
- $a87 = Dunkelbraun
- $999 = Mittelgrau
- $000 = Schwarz
-
- Nun ist das einzige Problem, den Copper dazu zu zwingen, unsere Copperlist
- auszuführen und die der Workbench bei Seite zu lassen. Aber da gibt´s noch
- ein anderes Problem: wenn wir unsere eigene ausführen lssen, wie schaffen
- wir es dann, den Orginalzustand wiederherzustellen? Antwort: Man muß auf
- ein Zettelchen aufschreiben, wo sie war!!! Oder anders: Wir schreiben in
- ein bestimmtes Longword die Adresse, an der sie zu finden ist. Wir werden
- dieses Longword OLDCOP nennen, also ALTE COPPERLIST, die des Systemes.
- Aber wen müssen wir fragen, um zu wissen, wo sich die Copperlist des
- Systemes befindet? Das Betriebssystem natürlich!!! Um es das zu fragen,
- müssen wir eine Routine aus dem CHIP des Kickstart ausführen! Um das zu
- tun, müssen wir immer als Bezug die Adresse nehmen, die in Adresse $4
- steht. Diese wird vom Kickstart geschrieben und enthält die Adresse, ab
- der wir unsere AdressierungsDistanzen (Offsetes) machen müssen. Diese sind
- vordefiniert, wir werden später darüber plaudern. Um das Long der Adresse
- $4 aufzusammeln, reicht ein:
-
- MOVE.L $4,a6 ; In a6 haben wir nun die ExecBase
-
- Oder besser:
-
- MOVE.L 4.w,a6 ; 4 ist eine kleine Zahl, deswegen kann 4.w
- ; geschrieben werden, was Platz spart.
- ; Es wird also $0004 statt $00000004 geschrieben,
- ; bei dem die ersten vier Nullen nicht gebraucht
- ; werden. VERSCHOBEN WIRD ABER IMMER EIN LONGWORD!
- ; Also das Long, das in Adresse 4, 5, 6 und 7
- ; enthalten ist.
-
- Ist einmal die Adresse, die in $4 enthalten war, in a6 kopiert, können wir
- darangehen, die Routinen des Kickis auszuführen, indem wir JSR verwenden,
- kombiniert mit der richtigen Distanz (Offset), denn es existieren ganz
- exakte Distanzen, die gewissen Routinen entsprechen. Nun wissen wir, daß
- z.B. mit einem JSR -$78(a6) das Multitasking abgeschalten wird!!! Es wird
- also nur unser Programm ausgeführt, nix anderes! Sofort testen! Ladet
- Listing3a.s in einen Buffer und startet es. Aber die Exec kümmert sich
- nicht um alles: der Kickstart, 256kB lang, wenn es sich um die Versionen
- 1.2 oder 1.3 handelt, oder 512k bei V2.0 und V3.0, ist in Libraries
- aufgeteilt, eine Art "Sammlung" von Routinen, die schon fertig sind und
- aufgerufen werden können. Und da jeder Kickstart anders ist, ja richtig
- hardwaremäßig, im Sinne daß die Routine, die das Multitasking abschaltet,
- im Kick 1.3 z.B. auf Adresse $fc1000 liegen könnte, während sie bei
- anderen Versionen irgendwo anders im Speicher sein könnte, haben die
- lieben Erbauer des Amiga eine ihrer wunderbaren Geistesblitze gehabt:
- "WARUM GEBEN WIR IN SPEICHERZELLE 4 NICHT EINE ADRESSE, VON DER AUS MAN
- IMMER DIE GLEICHEN ROUTINEN AUSFÜHREN KANN, WENN MAN MIT EINEM JSR EINEN
- BESTIMMTEN OFFSET ANSPRINGT?" (P.S. JSR ist das gleiche wie BSR, nur kann
- ein JSR Routinen im gesamten Speicher anspringen, während das BSR nur
- innherhalb 32768 Bytes nach vorne oder hinten operieren kann).
-
- Und das haben sie getan! Um z.B. das Disable, also das Multitasking
- killen, auszuführen, wird auf jedem Kickstart folgendes getan:
-
- move.l 4.w,a6 ; Adresse der Exec in a6
- jsr -$78(a6) ; Disable - blockiert Multitasking
- bsr.w MeinProgramm
- jsr -$7e(a6) ; Enabel -schaltet Multitasking wieder ein
-
- In jedem Kickstart liegt die Routine auf einer anderen Adresse, aber mit
- dieser Methode sind wir sicher, daß wir immer diese ausführen. Man muß nur
- alle Offsets der verschiedenen Routinen kennen, und das Spiel ist gemacht.
- Uns interessiert aber nur, die Copperlist des Betriebssystemes
- abzuspeichern, und um das zu schaffen, müssen wir und an eine Routine des
- Kick wenden, die Graphics.library heißt. Es ist die, die sich mit der
- Graphic befaßt, aber nur unter dem Betriebssystem, das sei klar, nicht auf
- Hardwareebene. Um auf diese Bibliothek (Library) zugreifen zu können,
- müssen wir sie zuerst öffnen:
-
- move.l 4.w,a6 ; ExecBase in a6 schreiben
- lea GfxName,a1 ; Adresse des Namens der Library, die
- ; es zu öffnen gilt, in a1
- JSR -$198(a6) ; OpenLibrary, Routine der Exec, die
- ; eine Bibliothek öffnet, und als Resultat
- ; die Basisadresse dieser zurückliefert
- ; (in d0), ab
- ; welcher wir die Offsets ansetzen müssen.
- move.l d0,GfxBase ; Speichere die Basisadresse der Gfx in
- ... ; GfxBase
- ...
-
- GfxBase:
- dc.b "graphics.library",0,0 ; BEMERKUNG: Um Charakter, also
- ; Buchstaben, in den Speicher zu
- ; geben, verwenden wir immer das
- ; dc.b und setzen sie unter ""oder´´
- GfxBase:
- dc.l 0
-
- In diesem Fall haben wir die Routine der Exec verwendet, die Bibliotheken
- öffnet, die "OpenLibrary". Sie verlangt, daß in a1 die Adresse steht, an
- der der Text mit dem Name der zu öffnenden Library zu finden ist. Wir
- hätten z.B. auch die "dos.library" öffnen können, um mit Files umzugehen,
- oder "intuition.library" für die Fenster, Screens etc. Einmal ausgeführt,
- liefert OpenLibrary in d0 die Basisadresse der gefragten Bibliothek., um
- uns zu verstehen, eine Adresse wie GfxBase, ab der wir dann mit JSR unsere
- Offsets machen, um die verschiedensten Routinen anzuspringen, die mit der
- Grafik zu tun haben. Außer den JSR wissen wir auch noch, daß die Adresse
- der aktuellen COPPERLIST des Systemes auf $26 nach GfxBase leigt, also
- fahren wir mit unserem Programm fort, indem wir diese Adresse in ein Label
- (OLDCOP) abspeichern:
-
- move.l 4.w,a6 ; ExecBase in a6 schreiben
- lea GfxName,a1 ; Adresse des Namens der Library, die
- ; es zu öffnen gilt, in a1
- JSR -$198(a6) ; OpenLibrary, Routine der Exec, die
- ; eine Bibliothek öffnet, und als Resultat
- ; die Basisadresse dieser in d0 zurückliefert,
- ; ab welcher wir die Offsets ansetzen müssen.
- move.l d0,GfxBase ; Speichere die Basisadresse der Gfx in
- ; GfxBase
-
- move.l d0,a6
- move.l $26(a6),OldCop ; Nun speichern wir die Adresse der z.Z
- ; aktuellen System-Copper in OLDCOP ab
- ....
-
- GfxName:
- dc.b "graphics.library",0,0 ; BEMERKUNG: Um Charakter, also
- ; Buchstaben, in den Speicher zu
- ; geben, verwenden wir immer das
- ; dc.b und setzen sie unter ""oder´´
- GfxBase:
- dc.l 0
-
- OldCop:
- dc.l 0
-
- Nun können wir unsere eigene Copperlist ansteuern, ein WaitMouse dazufügen
- und dann wieder den alten Zustand herstellen; mit ansteuern meine ich, daß
- wir die Adresse unserer Copperlist ins Register COP1LC geben, das ist das
- $dff080, das der Zeiger auf die sie ist, d.h. der Copper führt die
- Copperlist aus, deren Adresse sich im Register $dff080 befindet. Also,
- einmal die Adresse unserer Copperlist in $dff080, müssen wir sie noch
- "starten", indem wir ins Register $dff088 (COPJMP1) irgend einen Nonsens
- schreiben, egal, ob wir hineinschreiben oder was rauslesen, denn da es ein
- sog. STROBE-Register ist, reicht irgend eine Änderung, um es zu
- aktivieren. Die Strobe-Register sind wie eine Art Knopf, der grade mal
- berührt werden muß, um ausgelöst zu werden. Verwendet aber nicht CLR.W
- $dff088, das gibt komischerweise Probleme. Nun wird unsere Liste bei jedem
- Fotogramm ausgeführt, solange, bis in $dff080 nicht wieder eine andere
- kommt (oder besser, deren Adresse...!). Ein Problem ist, daß $dff080 ein
- NUR-SCHREIBE-REGISTER ist, probiert ein "=c 080" und ihr werdet das W
- bemerken (WRITE). Um die alte Copperlist - die, die der Asmone oder die
- Workbench verwendet- wieder an ihren Platz zu setzen, müssen wir das
- Betriebssystem fragen, welche Adresse in $dff080 enthalten ist, da dieses
- Register selbst ja nicht ausgelesen werden kann. Und dafür verwenden wir
- die Routine des Kickstart. Wenn wir dann diese Adresse erhalten haben,
- speichern wir sie in ein LONGWORD unseres Programmes, danach starten wir
- unsere einene Copperlist, und am Ende des Programmes geben wir die
- gespeicherte Adresse wieder in COP1LC ($dff080).
-
-
- move.l 4.w,a6 ; ExecBase in a6 schreiben
- JSR -78(a6) ; Disable - schaltet Multitasking aus
- lea GfxName,a1 ; Adresse des Namens der Library, die
- ; es zu öffnen gilt, in a1
- JSR -$198(a6) ; OpenLibrary, Routine der Exec, die
- ; eine Bibliothek öffnet, und als Resultat
- ; die Basisadresse dieser in d0 zurückliefert,
- ; ab welcher wir die Offsets ansetzen müssen.
- move.l d0,GfxBase ; Speichere die Basisadresse der Gfx in
- ; GfxBase
-
- move.l d0,a6
- move.l $26(a6),OldCop ; Nun speichern wir die Adresse der z.Z
- ; aktuellen System-Copper in OLDCOP ab
-
- move.l #COPPERLIST,$dff080 ; COP1LC-Wir zeigen auf unsere COP
- move.w d0,$dff088 ; COPJMP1-Wir starten unsere COP,
- ; indem wir etwas hineinschreiben,
- ; z.B. d0
- mouse:
- btst #6,$bfe001
- bne.s mouse
-
- move.l OldCop(PC),$dff080 ; COP1LC - Wir zeigen auf die alte
- ; System-Copperlist
- move.w d0,$dff088 ; COPJMP1 - und starten sie
-
- move.l 4.w,a6
- jsr -$7e(a6) ; Enable - schaltet Multitasking wieder ein
- move.l GfxBase(PC),a1 ; Base der zu schließenden Bibliothek
- ; (Bibliotheken werden IMMER geschloßen!!!)
- jsr -$19e(a6) ; Closelibrary - Schließt die graphics lib
- rts
-
-
- GfxName:
- dc.b "graphics.library",0,0 ; BEMERKUNG: Um Charakter, also
- ; Buchstaben, in den Speicher zu
- ; geben, verwenden wir immer das
- ; dc.b und setzen sie unter ""oder´´
- GfxBase:
- dc.l 0
-
- OldCop:
- dc.l 0
-
- COPPERLIST:
- dc.w $100,$200 ; BPLCON0 - Keine Bilder, nur Hintergrund
- dc.w $180,0 ; COLOR0 SCHWARZ
- dc.w $7f07,$FFFE ; WAIT - Warte auf Zeile $7f (127)
- dc.w $180,$00F ; COLOR0 BLAU
- dc.w $FFFF,$FFFE ; ENDE DER COPPERLIST
-
- Ihr werdet dieses Beispiel mit Vorschlägen und Änderungen in Listing3b.s
- finden. Holt es in den Buffer mit F2 oder einem x-beliebigen anderen und
- bestaunt das erste Programm aus dem Kurs, das den Chips des Amiga so
- richtig "Power unterm Hintern" macht.
-
- Habt ihr eure Experimente mit der Copperlist gemacht? Gut, nun versuchen
- wir, einige bewegte Effekte zu erzeugen. Bevor wir aber anfangen muß ich
- euch mitteilen, daß um irgend eine Bewegung zu machen, diese Routinen mit
- dem Elektronenstrahl, der das Bild auf dem Monitor zeichnet,
- synchronisiert werden müssen. Für die, die es noch nicht wissen, der
- Bildschirm wird 50 Mal pro Sekunde neu gezeichnet, und die Bewegungen, die
- uns flüssig erscheinen,z.B. die der besser programmierten Spiele, sind auf
- diese fünfzigstel Sekunde angepaßt. Wir haben das Register $dff006 schon
- verwende, das bekanntlich dauernd seinen Inhalt ändert. Aus gutem Grund,
- es beinhaltet ja die Position des Elektronenstrahles auf dem Monitor, und
- der düst mit 50 Seiten pro Sekunde durch die Gegend... Er startet bei 0,
- also dem höchten Teil des Monitors, ganz oben, und durchläuft ihn bis ganz
- unten. Wenn wir nun eine Routine schreiben, die Bewegungen auf den Schirm
- bringt, ohne sie zu zeitlich anzupassen, ohne Timing, dann wird sie mit
- der Geschwindigkeit des Prozessors laufen, also viel zu schnell um etwas
- zu sehen. Um eine gewisse Zeile des Bildschirmes abzuwarten müssen wir nur
- das erste Byte von $dff006 auslesen. In ihm steht die gerade erreichte
- Zeile, also die vertikale Position (gleich dem WAIT des COPPER):
-
- WaitZeile:
- CMPI.B #$f0,$dff006 ; VHPOSR - Sind wir auf Zeile $f0 ? (240)
- bne.s WaitZeile ; wenn nicht, kontrolliere nochmal
- ...
-
- Dieser Zyklus wartet die Zeile 240 ab, und erst dann fährt er mit den
- folgenden Befehlen fort, wie etwa die Routine, die auf einen Mausdruck
- wartet. Fügen wir auch diesen Teil ein:
-
- mouse:
- CMPI.B #$f0,$dff006 ; VHPOSR - Sind wir auf Zeile $f0 ? (240)
- bne.s mouse ; wenn nicht, kontrolliere nochmal
-
- BSR.s RoutineMitTiming ; Diese Routine wird nur einmal
- ; pro Fotogramm ausgeführt
-
- bsr.s MuoviCopper ; Die erste Bewegung am Bildschirm!!!!!
- btst #6,$bfe001 ; linke Maustaste gedrückt?
- bne.s mouse ; wenn nicht, zurück zu mouse:
- rts
-
- Jetzt haben wir eine Routine, die 1 Mal pro FRAME - oder Fotogramm -
- ausgeführt wird, also 1 Mal alle 50stel Sekunden, und um genau zu sein,
- wird sie jedesmal ausgeführt, wenn wir bei Zeile 240 angekommen sind, und
- dann wird sie ruhen, bis wir erneut Zeile 240 erreichen, dem nächstem
- FRAME.
-
- Bemerkung: Die Bilder werden mit der RASTER-Technik gezeichnet, die mit
- einem "ElektronenPinsel" links oben beginnt, nach rechts geht, bis zum
- Ende der Zeile, dann wieder ganz links, Zeile 2, usw. bis er am Ende des
- Bildschirms angekommen ist. Es ist mit dem Lesen vergleichbar: jede Zeile
- von links nahc rechts, angefangen bei der ersten ganz oben bis runter zur
- letzten auf der Seite, und DANN startet man wieder von vorne, so, als ob
- wir vergessen hätten, Seite zu wechseln. Denn der Monitor ist ja auch nur
- einer, und er muß nur auf dem einen Schirm schreiben, der Elektronenpinsel
- malt ja nicht auf die Wand.
-
- Ladet das Beispiel Listing3c.s in einen anderen Textbuffer und probiert es
- aus. Dieses bewegt ein WAIT nach unten und somit die folgende Farbe, wenn
- ihr die Maustaste drückt. Linke Taste zum Aussteigen.
-
- Listing3c.s verstanden? Dann lassen wir es ein bißchen schwiereiger
- werden! Ladet Listing3c2.s in einen Buffer und studiert es, ich habe eine
- Zeilenkontrolle eingefügt, um den Scroll zu stoppen.
-
- Alles klar in Listing3c2.s?? Gut, dann geht´s weiter mit der Praxis in
- Listing 3c3.s, in der ein Balken mit 10 WAIT verschoben wird, anstatt nur
- ein Wait alleine. Immer schwieriger!!!
-
- Lebt ihr noch nach Listing3c3.s? Dann massakriert euer Hirn mit dem
- nächsten Listing, dem Listing3c4.s, in der wir von 10 Label BALKEN auf ein
- einziges umsteigen, und die Adressierungsdistanz verwenden.
-
- Nun, es war ja nicht recht schwer, oder? Das Schwierige konne jetzt mit
- Listing 3d.s, in dem der Balken rauf und runter geht, und wir werden auch
- die Geschwindigkeit ändern.
-
- Habt ihr Listing3d.s verstanden? Ja? Glaub ich nicht! Euch kommt nur vor,
- ihr hättet verstanden... ich würde noch mal nachsehen, bevor ich
- weitergehen würde...na, noch mal angeschaut? Tja...dann holt euch eine
- Variante zum Thema rein mit Listing 3d2.s.
-
- Nun seid ihr bereit, Listing3e.s in Angriff zu nehmen, in der erklärt
- wird, wie man ein RASTERBAR herzaubert, also ein wiederholendes Fließen
- der Farben.
-
- Ein anderer Spezialfall: Wie erreiche ich die PAL-Zone (nach $FF) mit den
- Wait des Copper. Soviel in Listing3f.s.
-
- Um Lektion3.TXT abzuschließen, schaut euch Listing3g.s und Listing3h.s an,
- bei dem ein Verlauf von Links nach Rechts statt von oben nach unten
- erzielt wird. Danach seid ihr bereit, Lektion4.TXT durchzuackern. Dort
- wird die Verwaltung von farbigen Bildern und die möglichen Effekte auf
- ihnen behandelt!
-
- Bemerkung: Die Beispiele 4x.s der Lektion4.TXT befinden sich in der
- Directory Listings2, darum müßt ihr ein "V df0:Listings2" tippen, um die
- Bilder in dieser Directory laden zu können. Danach ladet Lektion4.TXT in
- diesen oder einen anderen Buffer (mit "r").
-
- * Komplimente, daß ihr bis hier her gekommen seid! Das Größte ist
- geschafft! Nun werden wir mit Leichtigkeit weitergehen, da wir in die
- Logik der Assemblerprogrammierung eingestiegen sind!
-
-
-